/*===========================================================
 
 .---=||||[ B L O O D Y ]|||||=====================----------....
 |                                                              |
 |    THE  M O S T   B L O O D Y  GAME EVER!                    |
 |                                                              |
 |    bloody harvest is coming... soon,                         |
 |                                              heil Satan!     |
 !                                                              !
 .                                                              ,
  ~~~~-------------================================|||||||||==-~




 Name-Space: {core, logic, editor}
 Module: {draw, coll, scgr, ...}
 Class: <name of class>
 Last modification:  <author>, <time>

 TODO:
 <-------- todo #1 ---------->
 <-------- todo #2 ---------->
 <-------- todo #3 ---------->
        ............
 <-------- todo #n ---------->

 FIX:
 <-------- fix #1 ----------->
 <-------- fix #1 ----------->
         ..........
 <-------- fix #n ----------->




 
 
 ============================================================*/
#include "core/draw/Camera.h"
#include "core/Timer.h"
using namespace std;
namespace core
{
	namespace draw
	{


	  FollowCam::FollowCam()
	  {
			lastTime = -1.0;
	  }

	  FollowCam::~FollowCam()
	  {
	  }

	  void FollowCam::place()
	  {
			double now = Timer::time();
			if (lastTime < 0)
			{
				lastTime = now;
			}
			
			double delta = now - lastTime;
			lastTime = now;

			double r = delta / 0.5;
			if (r > 1)
			{
				r = 1;
			}
			//cout << r << endl;

			curPos = curPos.lerp(r, position);
			curLookAt = curLookAt.lerp(r, lookAt);

			// gluLookAt(position.x, position.y, position.z, lookAt.x, lookAt.y, lookAt.z, up.x, up.y, up.z);
			gluLookAt(curPos.x, curPos.y, curPos.z, curLookAt.x, curLookAt.y, lookAt.z, up.x, up.y, up.z);
	  }


		//================================================[ FPCam ]==================================----



	  FPCam::FPCam()
	  {
	    rotation = Quatf(1,0,0,0);
	  }

	  FPCam::~FPCam()
	  {
	  }

	  void FPCam::place()
	  {
	     glLoadIdentity();
	     Matrix4f mrot = rotation.transform();
	     Matrix4f mtrans = Matrix4f::createTranslation(-position.x, -position.y, -position.z);
	     glMultMatrixf( mtrans * mrot);
	  }




		//================================================[ FPSCam ]==================================----




	  FPSCam::FPSCam()
	  {
	    position = Vector3f(0,0,0);
	    azimut = zenit = 0;
	  }

	  FPSCam::~FPSCam()
	  {
	  }

	  void FPSCam::place()
	  {
	    glRotatef(zenit, 1,0,0);
	    glRotatef(azimut, 0,1,0);

	    glTranslatef(-position.x, -position.y, -position.z);
	  }



	  void FPSCam::moveForward(float len)
	  {
	    Vector3f fwd(0,0,-len);
	    fwd = rotMat() * fwd;
	    
	    position += fwd;
	  }


	  void FPSCam::moveBackward(float len)
	  {
	    Vector3f fwd(0,0,-len);
	    fwd = rotMat() * fwd;
	    
	    position -= fwd;
	  }

	  void FPSCam::moveRight(float len)
	  {
	    Vector3f fwd(len,0,0);
	    fwd = rotMat() * fwd;
	    
	    position += fwd;
	  }

	  void FPSCam::moveLeft(float len)
	  {
	    Vector3f fwd(len,0,0);
	    fwd = rotMat() * fwd;
	    
	    position -= fwd;
	  }

		inline Matrix3f FPSCam::rotMat()
		{
	    Matrix3f rotX = Matrix3f::createRotationAroundAxis(DEG2RAD(zenit),0,0);
			Matrix3f rotY = Matrix3f::createRotationAroundAxis(0,DEG2RAD(azimut), 0);
			return rotY * rotX;
		}

	}
}
